const { Op } = require('sequelize')
const R = require('@/models/Response')
const { Role, Permission } = require('@/models/model')
const { getPermissionByIds } = require('@/utils/getModelInfo')
const { arraysIsEqual } = require('@/utils/common')
const { LOG_TYPE } = require('@/constants/log')

/**
 * @author: Hejh(3010733382@qq.com)
 * @description: 单角色修改时验证参数与数据库发生变化没，如果没有，则无需更新
 * @param {*} ctx
 * @param {*} next
 */
module.exports.singerUpdateCheck = async (ctx, next) => {
  // 进行角色是否需要更新的必要检测
  const { roleId, name, desc, label, isVisible, permissionIds } =
    ctx.request.body
  ctx.logs = [
    {
      roleId,
      update: {
        role: {
          name,
          id: roleId
        },
        permissions: []
      }
    }
  ]
  let needUpdate = false

  const role = await Role.findByPk(BigInt(roleId), {
    attributes: ['id', 'name', 'label', 'desc', 'isVisible', 'type'],
    include: {
      model: Permission,
      as: 'Permissions',
      attributes: ['id', 'name', 'ename']
    }
  })

  // console.log(role.Permissions, 'role')

  ctx.logs[0].type =
    +role.type === 0 ? LOG_TYPE.SYSTEM_ROLE_UPDATE : LOG_TYPE.DOC_ROLE_UPDATE

  const oldPermissionIds = role.Permissions.map((item) => item.id)

  const curLog = ctx.logs[0].update
  curLog.role.type = role.type
  if (role.name !== name) {
    curLog.role.name = name
    needUpdate = true
  }
  if (desc && desc !== role.desc) {
    curLog.role.desc = desc
    needUpdate = true
  }
  if (role.label !== label) {
    curLog.role.label = label
    needUpdate = true
  }
  if (+role.isVisible !== +isVisible) {
    curLog.role.isVisible = isVisible
    needUpdate = true
  }

  if (!arraysIsEqual(oldPermissionIds, permissionIds)) {
    curLog.permissions = await getPermissionByIds(permissionIds)
    needUpdate = true
  }

  if (needUpdate) {
    await next()
  } else {
    ctx.body = R.success()
    return
  }
}

/**
 * @author: Hejh(3010733382@qq.com)
 * @description: 删除角色时，将需要删除的角色信息预先保存
 * @param {*} ctx
 * @param {*} next
 */
module.exports.delRolesSave = async (ctx, next) => {
  let { roleIds } = ctx.request.body
  roleIds = roleIds.map((item) => BigInt(item))
  const roles = await Role.findAll({
    attributes: ['id', 'name', 'type'],
    where: {
      id: {
        [Op.in]: roleIds
      }
    }
  })
  ctx.logs = roles.map((item) => {
    return {
      type:
        +item.type === 0
          ? LOG_TYPE.SYSTEM_ROLE_DELETE
          : LOG_TYPE.DOC_ROLE_DELETE,
      role: {
        id: item.id,
        name: item.name,
        type: item.type
      }
    }
  })
  await next()
}
